package com.anji.sp.push.service.impl;

import com.alibaba.fastjson.JSON;
import com.anji.sp.enums.IsDeleteEnum;
import com.anji.sp.enums.RepCodeEnum;
import com.anji.sp.enums.UserStatus;
import com.anji.sp.model.ResponseModel;
import com.anji.sp.push.emuns.PushTargetTypeEnum;
import com.anji.sp.push.mapper.PushHistoryMapper;
import com.anji.sp.push.model.MessageModel;
import com.anji.sp.push.model.po.PushHistoryPO;
import com.anji.sp.push.model.vo.PushHistoryVO;
import com.anji.sp.push.model.vo.RequestSendBean;
import com.anji.sp.push.service.PushHistoryService;
import com.anji.sp.util.APPVersionCheckUtil;
import com.anji.sp.util.BeanUtils;
import com.anji.sp.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * 推送历史表 服务实现类
 * </p>
 *
 * @author kean
 * @since 2021-01-20
 */
@Service
@Slf4j
public class PushHistoryServiceImpl extends ServiceImpl<PushHistoryMapper, PushHistoryPO> implements PushHistoryService {

    @Autowired
    private PushHistoryMapper pushHistoryMapper;

    /** 根据数据库必填项，校验是否为空，不校验主键
     * @param pushHistoryVO
     * @return
     */
    private ResponseModel validateCreateFieldNotNull(PushHistoryVO pushHistoryVO){
        if(pushHistoryVO == null){
            return RepCodeEnum.NULL_ERROR.parseError("requestModel data");
        }
        /* 该片段由生成器产生，请根据实际情况修改
        if(pushHistoryVO.getId() == null){
            return RepCodeEnum.NULL_ERROR.parseError("id");
        }
        if(StringUtils.isBlank(pushHistoryVO.getAppKey())){
            return RepCodeEnum.NULL_ERROR.parseError("appKey");
        }
        if(StringUtils.isBlank(pushHistoryVO.getMsgId())){
            return RepCodeEnum.NULL_ERROR.parseError("msgId");
        }
        if(StringUtils.isBlank(pushHistoryVO.getTitle())){
            return RepCodeEnum.NULL_ERROR.parseError("title");
        }
        if(StringUtils.isBlank(pushHistoryVO.getContent())){
            return RepCodeEnum.NULL_ERROR.parseError("content");
        }
        if(StringUtils.isBlank(pushHistoryVO.getExtras())){
            return RepCodeEnum.NULL_ERROR.parseError("extras");
        }
        if(StringUtils.isBlank(pushHistoryVO.getSendOrigin())){
            return RepCodeEnum.NULL_ERROR.parseError("sendOrigin");
        }
        if(StringUtils.isBlank(pushHistoryVO.getPushType())){
            return RepCodeEnum.NULL_ERROR.parseError("pushType");
        }
        if(StringUtils.isBlank(pushHistoryVO.getChannel())){
            return RepCodeEnum.NULL_ERROR.parseError("channel");
        }
        if(StringUtils.isBlank(pushHistoryVO.getPushResult())){
            return RepCodeEnum.NULL_ERROR.parseError("pushResult");
        }
        if(pushHistoryVO.getSendTime() == null){
            return RepCodeEnum.NULL_ERROR.parseError("sendTime");
        }
        if(pushHistoryVO.getEnableFlag() == null){
            return RepCodeEnum.NULL_ERROR.parseError("enableFlag");
        }
        if(pushHistoryVO.getDeleteFlag() == null){
            return RepCodeEnum.NULL_ERROR.parseError("deleteFlag");
        }
        if(pushHistoryVO.getCreateBy() == null){
            return RepCodeEnum.NULL_ERROR.parseError("createBy");
        }
        if(pushHistoryVO.getCreateDate() == null){
            return RepCodeEnum.NULL_ERROR.parseError("createDate");
        }
        if(pushHistoryVO.getUpdateBy() == null){
            return RepCodeEnum.NULL_ERROR.parseError("updateBy");
        }
        if(pushHistoryVO.getUpdateDate() == null){
            return RepCodeEnum.NULL_ERROR.parseError("updateDate");
        }
        if(StringUtils.isBlank(pushHistoryVO.getRemarks())){
            return RepCodeEnum.NULL_ERROR.parseError("remarks");
        }
        */
        return ResponseModel.success();
    }

    /**
     * 保存到推送消息历史中
     *
     * @param requestSendBean
     * @param messageModel
     */
    @Override
    public ResponseModel savePushHistory(RequestSendBean requestSendBean, MessageModel messageModel, String msgId, String targetType) {
        PushHistoryVO pushHistoryVO = new PushHistoryVO();
        pushHistoryVO.setAppKey(requestSendBean.getAppKey());
        pushHistoryVO.setTitle(requestSendBean.getTitle());
        pushHistoryVO.setContent(requestSendBean.getContent());
        pushHistoryVO.setAndroidConfig(JSON.toJSONString(requestSendBean.getAndroidConfig()));
        pushHistoryVO.setIosConfig(JSON.toJSONString(requestSendBean.getIosConfig()));
        if ("1".equals(requestSendBean.getPushType())) {//透传
            pushHistoryVO.setChannel("1");
            pushHistoryVO.setPushType("1");
        } else {
            pushHistoryVO.setChannel("0");
            pushHistoryVO.setPushType("0");
        }
        //消息发送总数
        pushHistoryVO.setTargetNum(requestSendBean.getRegistrationIds().size() + "");
        pushHistoryVO.setSuccessNum(messageModel.getSuccessNum());
        //消息发送msgId
        pushHistoryVO.setMsgId(msgId);
        //设置消息发送品牌类型
        pushHistoryVO.setTargetType(targetType);
        pushHistoryVO.setRemarks(messageModel.getMessage());
        return create(pushHistoryVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseModel create(PushHistoryVO pushHistoryVO) {
        //参数校验
        ResponseModel valid = validateCreateFieldNotNull(pushHistoryVO);
        if(valid.isError()){
            return valid;
        }
        //业务校验
        //...todo

        //业务处理
        if(pushHistoryVO.getEnableFlag()==null){
            pushHistoryVO.setEnableFlag(UserStatus.OK.getIntegerCode());
        }
        pushHistoryVO.setDeleteFlag(IsDeleteEnum.NOT_DELETE.getIntegerCode());
        pushHistoryVO.setUpdateBy(1L);
        pushHistoryVO.setCreateDate(LocalDateTime.now());
        pushHistoryVO.setUpdateBy(1L);
        pushHistoryVO.setUpdateDate(LocalDateTime.now());
        pushHistoryVO.setSendTime(LocalDateTime.now());

        PushHistoryPO pushHistoryPO = new PushHistoryPO();
        BeanUtils.copyProperties(pushHistoryVO, pushHistoryPO);
        boolean flag = save(pushHistoryPO);

        //返回结果
        if(flag){
            return ResponseModel.successData(pushHistoryPO);
        }else{
            return ResponseModel.errorMsg(RepCodeEnum.ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseModel updateById(PushHistoryVO pushHistoryVO) {
        //参数校验
        if(pushHistoryVO == null){
            return RepCodeEnum.NULL_ERROR.parseError("requestModel data");
        }
        Long pushHistoryId = pushHistoryVO.getId();
        if(pushHistoryId == null){
            return RepCodeEnum.NULL_ERROR.parseError("pushHistoryId");
        }
        //业务校验
        //...todo

        //业务处理
        PushHistoryPO pushHistoryPO = getById(pushHistoryId);
        if(pushHistoryPO == null){
            return RepCodeEnum.NOT_EXIST_ERROR.parseError("pushHistoryId="+pushHistoryId.longValue());
        }
        pushHistoryVO.setUpdateBy(1L);
        pushHistoryVO.setUpdateDate(LocalDateTime.now());
        BeanUtils.copyProperties(pushHistoryVO, pushHistoryPO, true);
        boolean flag = updateById(pushHistoryPO);

        //返回结果
        if(flag){
            return ResponseModel.successData(pushHistoryPO);
        }else{
            return ResponseModel.errorMsg("修改失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseModel deleteById(PushHistoryVO pushHistoryVO) {
        //参数校验
        if(pushHistoryVO == null){
            return RepCodeEnum.NULL_ERROR.parseError("requestModel data");
        }
        Long pushHistoryId = pushHistoryVO.getId();
        if(pushHistoryId == null){
            return RepCodeEnum.NULL_ERROR.parseError("pushHistoryId");
        }

        //业务处理
        PushHistoryPO pushHistoryPO = getById(pushHistoryId);
        if(pushHistoryPO == null){
            return RepCodeEnum.NOT_EXIST_ERROR.parseError("pushHistoryId="+pushHistoryId.longValue());
        }
        boolean flag = removeById(pushHistoryId);

        //返回结果
        if(flag){
            return ResponseModel.successData("删除成功");
        }else{
            return ResponseModel.errorMsg("删除失败");
        }
    }

    @Override
    public ResponseModel queryById(PushHistoryVO pushHistoryVO) {
        //参数校验
        if(pushHistoryVO == null){
            return RepCodeEnum.NULL_ERROR.parseError("requestModel data");
        }
        Long pushHistoryId = pushHistoryVO.getId();
        if(pushHistoryId == null){
            return RepCodeEnum.NULL_ERROR.parseError("pushHistoryId");
        }

        //业务处理
        PushHistoryPO pushHistoryPO = getById(pushHistoryId);
        if(pushHistoryPO == null){
            return RepCodeEnum.NOT_EXIST_ERROR.parseError("pushHistoryId="+pushHistoryId.longValue());
        }

        //返回结果
        BeanUtils.copyProperties(pushHistoryPO, pushHistoryVO);
        return ResponseModel.successData(pushHistoryVO);
    }

    @Override
    public ResponseModel queryByPage(PushHistoryVO pushHistoryVO) {
        //参数校验
        if(pushHistoryVO == null){
            return RepCodeEnum.NULL_ERROR.parseError("requestModel data");
        }
        //...todo

        //分页参数
        Page<PushHistoryVO> page = new Page<PushHistoryVO>(pushHistoryVO.getPageNo(), pushHistoryVO.getPageSize());
        pushHistoryVO.setDeleteFlag(IsDeleteEnum.NOT_DELETE.getIntegerCode());

        //业务处理
        IPage<PushHistoryVO> pageList = pushHistoryMapper.queryByPage(page, pushHistoryVO);

        //返回结果
        return ResponseModel.successData(pageList);
    }

    @Override
    public ResponseModel queryByMsgId(PushHistoryVO vo, int i) {
        if (StringUtils.isBlank(vo.getAppKey())){
            return RepCodeEnum.NULL_ERROR.parseError("appKey");
        }
        if (StringUtils.isBlank(vo.getMsgId())){
            return RepCodeEnum.NULL_ERROR.parseError("msgId");
        }
        QueryWrapper<PushHistoryPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("app_key", vo.getAppKey());
        queryWrapper.eq("msg_id", vo.getMsgId());
        List<PushHistoryPO> pushHistoryPOS = pushHistoryMapper.selectList(queryWrapper);
        List<PushHistoryPO> pushHistoryList = new ArrayList<>();

        //华为
        List<PushHistoryPO> hwCollects = pushHistoryPOS.stream().filter(s -> s.getTargetType().equals(PushTargetTypeEnum.HW.getCode())).collect(Collectors.toList());
        //小米
        List<PushHistoryPO> xmCollects = pushHistoryPOS.stream().filter(s -> s.getTargetType().equals(PushTargetTypeEnum.XM.getCode())).collect(Collectors.toList());
        //oppo
        List<PushHistoryPO> opCollects = pushHistoryPOS.stream().filter(s -> s.getTargetType().equals(PushTargetTypeEnum.OP.getCode())).collect(Collectors.toList());
        //vivo
        List<PushHistoryPO> voCollects = pushHistoryPOS.stream().filter(s -> s.getTargetType().equals(PushTargetTypeEnum.VO.getCode())).collect(Collectors.toList());
        //jgIOS
        List<PushHistoryPO> iOSCollects = pushHistoryPOS.stream().filter(s -> s.getTargetType().equals(PushTargetTypeEnum.JG_IOS.getCode())).collect(Collectors.toList());
        //jgAndroid
        List<PushHistoryPO> androidCollects = pushHistoryPOS.stream().filter(s -> s.getTargetType().equals(PushTargetTypeEnum.JG_ANDROID.getCode())).collect(Collectors.toList());

        if (hwCollects.size()>0){
            pushHistoryList.add(getPushCollection(hwCollects, i));
        }
        if (xmCollects.size()>0){
            pushHistoryList.add(getPushCollection(xmCollects, i));
        }
        if (opCollects.size()>0){
            pushHistoryList.add(getPushCollection(opCollects, i));
        }
        if (voCollects.size()>0){
            pushHistoryList.add(getPushCollection(voCollects, i));
        }
        if (iOSCollects.size()>0){
            pushHistoryList.add(getPushCollection(iOSCollects, i));
        }
        if (androidCollects.size()>0){
            pushHistoryList.add(getPushCollection(androidCollects, i));
        }

        return ResponseModel.successData(pushHistoryList);
    }

    private PushHistoryPO getPushCollection(List<PushHistoryPO> collects, int i){
        AtomicInteger targetNum = new AtomicInteger(0);
        AtomicInteger successNum = new AtomicInteger(0);
        StringBuilder remarks = new StringBuilder();
        collects.forEach(s->{
            if (StringUtils.isNotBlank(s.getRemarks())){
                if (StringUtils.isNotBlank(remarks)){
                    remarks.append("\n");
                }
                remarks.append(s.getRemarks());
            }
            targetNum.addAndGet(APPVersionCheckUtil.strToInt(s.getTargetNum()));
            successNum.addAndGet(APPVersionCheckUtil.strToInt(s.getSuccessNum()));
        });
        PushHistoryPO p = collects.get(0);
        p.setSuccessNum(successNum.toString());
        p.setTargetNum(targetNum.toString());
        if (i == 0){
            p.setRemarks(remarks.toString().replaceAll("\n", "</br>"));
        } else {
            p.setRemarks(remarks.toString());
        }
        return p;
    }

}
